package com.xmut.mall.member.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.additional.update.impl.UpdateChainWrapper;
import com.xmut.mall.member.constant.AuthConstant;
import com.xmut.mall.member.searchparam.MemberComponentsSearchParam;
import com.xmut.mall.member.utils.PageUtil;
import com.xmut.mall.member.utils.RespBean;
import com.xmut.mall.member.vo.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Map;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xmut.mall.member.utils.PageUtils;
import com.xmut.mall.member.utils.Query;

import com.xmut.mall.member.dao.MemberDao;
import com.xmut.mall.member.entity.MemberEntity;
import com.xmut.mall.member.service.MemberService;
import org.springframework.util.StringUtils;


@Service("memberService")
public class MemberServiceImpl extends ServiceImpl<MemberDao, MemberEntity> implements MemberService {

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<MemberEntity> page = this.page(
                new Query<MemberEntity>().getPage(params),
                new QueryWrapper<MemberEntity>()
        );

        return new PageUtils(page);
    }

    /**
     * 注册用户
     *
     * @param vo
     * @return
     */
    @Override
    public RespBean registerUser(RegisterVo vo) {
        Integer phoneCount = this.baseMapper.selectCount(new QueryWrapper<MemberEntity>().eq("mobile", vo.getMobilePhone()));
        Integer usernameCount = this.baseMapper.selectCount(new QueryWrapper<MemberEntity>().eq("username", vo.getUsername()));

        if (phoneCount != 0) {
            // 该手机号已被注册 直接返回错误
            return RespBean.error("该手机号码已被注册");
        }

        if (usernameCount != 0) {
            // 该用户名已被注册
            return RespBean.error("该用户名已被注册");
        }

        // 如果用户名和手机号都可用就进行注册
        MemberEntity member = new MemberEntity();
        member.setUsername(vo.getUsername());
        // 密码加密;
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        member.setPassword(passwordEncoder.encode(vo.getPassword()));
        member.setMobile(vo.getMobilePhone());
        member.setHeader("https://xmut-mall.oss-cn-hangzhou.aliyuncs.com/2022-10-21/1.jpg");// 默认头像 在个人中心可修改
        member.setCreateTime(new Date());// 创建时间

        int insert = this.baseMapper.insert(member);
        if (insert > 0) {
            // 注册成功
            member.setPassword(null);
            return RespBean.success("注册成功", member);
        } else {
            // 注册失败
            return RespBean.error("注册失败");
        }
    }

    /**
     * 用户登录
     *
     * @param vo
     * @return
     */
    @Override
    public RespBean login(LoginVo vo) {
        // 查询当前用户
        MemberEntity userInfo = this.baseMapper.selectOne(new QueryWrapper<MemberEntity>()
                .eq("username", vo.getUsername())
                .or().eq("mobile", vo.getUsername()));
        if (userInfo == null) {
            // 查询数据库没有结果
            return RespBean.error("用户不存在");
        } else {
            // 数据库有结果进行密码对比
            BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
            boolean result = passwordEncoder.matches(vo.getPassword(), userInfo.getPassword());
            if (result) {
                // 密码正确
                return RespBean.success("查询用户成功", userInfo);
            } else {
                // 密码错误
                return RespBean.error("密码错误");
            }
        }
    }

    /**
     * 根据手机号码查询用户
     *
     * @param phone
     * @return
     */
    @Override
    public RespBean getUserByPhone(String phone) {
        MemberEntity member = this.baseMapper.selectOne(new QueryWrapper<MemberEntity>().eq("mobile", phone));
        if (member == null) {
            return RespBean.error("该手机号码并未注册");
        }
        return RespBean.success("获取用户成功", member);
    }

    /**
     * 根据手机号码重置密码
     *
     * @param vo
     * @return
     */
    @Override
    public RespBean resetPassword(ResetPasswordVo vo) {
        // 因为之前已经验证过手机号码了 这里就不做用户验证了
        // 密码加密
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        vo.setPassword(passwordEncoder.encode(vo.getPassword()));
        boolean update = this.update(new UpdateWrapper<MemberEntity>()
                .set("password", vo.getPassword())
                .eq("mobile", vo.getMobile()));
        if (update) {
            // 删掉验证手机号时存入的uuid
            redisTemplate.delete(AuthConstant.SMS_RESETPASSWORD_CACHE_PREFIX + vo.getMobile());
            return RespBean.success("修改密码成功");
        } else {
            return RespBean.error("修改密码错误");
        }
    }

    /**
     * @param vo
     * @return
     */
    @Override
    public MemberEntity editUserInfo(EditMemberVo vo) {
        MemberEntity member = this.getById(vo.getId());
        member.setNickname(vo.getNickname());
        member.setBirth(vo.getBirthday());
        member.setGender(vo.getSex());
        member.setHeader(vo.getHeader());
        this.updateById(member);
        return member;
    }

    /**
     * 检查该用户是否设置了密码
     *
     * @param userId
     * @return
     */
    @Override
    public Boolean checkPwdStatus(Long userId) {
        String password = this.getById(userId).getPassword();
        if (StringUtils.isEmpty(password)) {
            // 如果是null就是没有密码
            return false;
        } else {
            // 如果不是空就说明设置了密码
            return true;
        }

    }

    /**
     * 根据用户id修改密码
     *
     * @param vo
     * @return
     */
    @Override
    public Boolean editPwd(EditPassWordVo vo) {
        MemberEntity member = this.baseMapper.selectById(vo.getUserId());
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        if (!encoder.matches(vo.getPassword(), member.getPassword())) {
            // 如果密码对不上直接返回错误
            return false;
        }
        // 数据库修改密码
        boolean update = this.update(new UpdateWrapper<MemberEntity>()
                .eq("id", vo.getUserId())
                .set("password", encoder.encode(vo.getNewPassword())));
        if (update) {
            // 数据库修改成功
            return true;
        } else {
            return false;
        }
    }

    /**
     * 获取商城官方管理端的会员选择组件的分页数据
     *
     * @param vo
     * @param param
     * @return
     */
    @Override
    public RespBean getManagerMemberComponentsPage(PageVO vo, MemberComponentsSearchParam param) {
        IPage<ManagerMemberComponentsPageVo> page = this.baseMapper.getManagerMemberComponentsPage(PageUtil.initPage(vo), param);

        return RespBean.success("获取成功", page);
    }


}